package com.deceen.common.filters;

import com.alibaba.fastjson.JSONObject;
import com.deceen.common.VO.ParkingToken;
import com.deceen.common.VO.UserInfo;
import com.deceen.common.utils.HttpUtil;
import com.deceen.common.utils.JwtTokenUtil;
import com.deceen.common.utils.RedisClientUtil;
import com.deceen.demo.dao.UserMapper;
import com.deceen.demo.entity.UserEntityEo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义 JSON 登录
 */
@Slf4j
public class PasswordLoginFilter extends AbstractAuthenticationProcessingFilter {

    private final UserMapper userService;
    private final PasswordEncoder passwordEncoder;
    private RedisClientUtil redisClientUtil;

    public PasswordLoginFilter(String defaultFilterProcessesUrl, UserMapper userService, PasswordEncoder passwordEncoder,RedisClientUtil redisClientUtil) {
        super(new AntPathRequestMatcher(defaultFilterProcessesUrl, HttpMethod.POST.name()));
        this.redisClientUtil = redisClientUtil;
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
        JSONObject requestBody = HttpUtil.getRequestBody(httpServletRequest);

        String username = requestBody.getString("username");
        String password = requestBody.getString("password");
        UserInfo userInfo = validateUsernameAndPassword(username, password);

        List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
        simpleGrantedAuthorities.add(new SimpleGrantedAuthority("USER"));

        String token = JwtTokenUtil.generateToken(userInfo.getUserName());
        redisClientUtil.storeToken(userInfo.getUserName(),token);

        return new ParkingToken(userInfo,token,simpleGrantedAuthorities);
    }

    /**
     * 校验用户名和密码
     */
    private UserInfo validateUsernameAndPassword(String username, String password) throws AuthenticationException {
        UserEntityEo user = userService.getUser(username);
        if (user == null){
            throw new UsernameNotFoundException("user not exist");
        }
        if(!user.getPassword().equals(passwordEncoder.encode(password))){
            throw new AuthenticationServiceException("error username or password");
        }
        return new UserInfo(user.getId().toString(),user.getUsername());
    }

}
